package com.sls.game.service.impl;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import com.google.gson.Gson;
import com.sls.core.common.CommonUtil;
import com.sls.core.http.HttpClient;
import com.sls.core.socket.Head;
import com.sls.core.socket.ServerDisponseException;
import com.sls.core.util.UtilMD5Encryption;
import com.sls.game.constant.ExceptionCodeDes;
import com.sls.game.parser.nutsnet.NutsNetAssembleHttpUrl;
import com.sls.game.parser.nutsnet.TradeResponseSaxParseXml;
import com.sls.game.pojo.NutsNetServerInfo;
import com.sls.game.pojo.NutsNetTradeParameter;
import com.sls.game.pojo.NutsNetTradeResInfo;
import com.sls.game.service.NutsNetTradeService;

/**
 * @Description 交易接口
 * @author Wangxuegang
 * @date 2012-09-03
 */
@Service("nutsNetTradeService")
public class NutsNetTradeServiceImpl implements NutsNetTradeService {
	private static Logger log = Logger.getLogger(NutsNetTradeServiceImpl.class);

	private Gson gson = null;

	public NutsNetTradeServiceImpl() {
		gson = CommonUtil.gson();
	}

	/**
	 * 订单处理方法
	 * 
	 * @throws ServerDisponseException
	 */
	@Override
	public String insert(String body, Head head) throws ServerDisponseException {
		if (log.isInfoEnabled()) {
			log.info("进入Service开始处理[" + head.getRequestId() + "]的请求");
		}
		// 对消息body进行解析
		NutsNetTradeParameter parameterInfo = gson.fromJson(body,
				NutsNetTradeParameter.class);

		// 商品充值类型
		String productType = "2";
		// 从配置文件中获取密钥
		NutsNetServerInfo serverInfo = NutsNetAssembleHttpUrl.getKeyValue();
		String partnerKey = serverInfo.getPartnerKey(); // 为合作方商户密钥
		String supUserKey = serverInfo.getSupUserKey(); // 为合作方用户密钥

		boolean flag = checkData(parameterInfo, head.getRequestId(),
				productType);
		if (flag) { // 数据校验通过
			try {
				// 签名字符串
				String sign = createSignStr(parameterInfo, productType,
						partnerKey, supUserKey);
				if (!("".equals(sign)) && sign != null) {
					parameterInfo.setSign(sign);
				}

				String paraStr = assembleParameter(parameterInfo);
				// 坚果网络接口服务path
				String path = "OrderTrade.aspx";
				String url = NutsNetAssembleHttpUrl.assembleHttpUrl(paraStr,
						path);
				// 发送http请求
				NutsNetTradeResInfo resInfo = sendHttpRequest(url);
				String resultBody = null;
				if (resInfo != null) {
					resultBody = gson.toJson(resInfo);
				}
				log.info("返回消息：  " + resultBody);
				if (log.isInfoEnabled()) {
					log.info("Service处理[" + head.getRequestId() + "]的请求已结束");
				}
				return resultBody;
			} catch (Exception e) {
				log.error("Service处理[" + head.getRequestId() + "]异常！");
				throw new ServerDisponseException(
						ExceptionCodeDes.ACCESS_DATABASE_ERROR.getCode(),
						ExceptionCodeDes.ACCESS_DATABASE_ERROR.getDescription());
			}
		}

		return null;
	}

	/**
	 * 发送http请求，并对返回的xml格式的结果进行解析
	 * 
	 * @param url
	 * @return
	 */
	private NutsNetTradeResInfo sendHttpRequest(String url) {
		NutsNetTradeResInfo resInfo = null;
		HttpClient httpClient = new HttpClient();
		try {
			// 供应商返回消息编码方式
			String supplyEncode = "GBK";
			String xmlStr = httpClient.doGet(url, supplyEncode);
			// 对返回的xml格式字符串数据进行解析
			List<NutsNetTradeResInfo> tradeResList = TradeResponseSaxParseXml
					.parseXmlString(xmlStr);
			if (tradeResList.size() > 0) {
				for (int i = 0; i < tradeResList.size(); i++) {
					resInfo = tradeResList.get(i);
				}
				return resInfo;
			}
		} catch (Exception e) {
			log.error(e);
		}

		return resInfo;
	}

	/**
	 * 数据校验
	 */
	private boolean checkData(NutsNetTradeParameter parameterInfo,
			String reqId, String productType) throws ServerDisponseException {
		boolean flag = false;
		// 合作平台编号
		String partnerId = parameterInfo.getPartnerId();
		// 合作方用户编号
		String supUserId = parameterInfo.getSupUserId();
		// 商品中心商品编号
		String supProductId = parameterInfo.getSupProductId();
		// 合作方平台订单编号
		String ptOrderNo = parameterInfo.getPtOrderNo();
		// 合作方买家付款时间
		String ptPayTime = parameterInfo.getPtPayTime();
		// 购买数量
		String buyNum = parameterInfo.getBuyNum();
		// Sup供货价格单价
		String unitPrice = parameterInfo.getUnitPrice();
		// 总价
		String sum = parameterInfo.getSum();
		// 充值账号
		String accountVal = parameterInfo.getAccountVal();
		// 最终购买用户IP地址
		String buyerIp = parameterInfo.getBuyerIp();
		// 异同通知地址
		String notifyUrl = parameterInfo.getNotifyUrl();

		if ("".equals(partnerId) || partnerId == null) {
			throw new ServerDisponseException(
					ExceptionCodeDes.COOPERATION_PLATFORMNO_NULL.getCode(),
					ExceptionCodeDes.COOPERATION_PLATFORMNO_NULL
							.getDescription());
		} else if ("".equals(supUserId) || supUserId == null) {
			throw new ServerDisponseException(
					ExceptionCodeDes.COOPERATION_USERNO_NULL.getCode(),
					ExceptionCodeDes.COOPERATION_USERNO_NULL.getDescription());
		} else if ("".equals(supProductId) || supProductId == null) {
			throw new ServerDisponseException(
					ExceptionCodeDes.GOODS_ID_EMPTY.getCode(),
					ExceptionCodeDes.GOODS_ID_EMPTY.getDescription());
		} else if ("".equals(ptOrderNo) || ptOrderNo == null) {
			throw new ServerDisponseException(
					ExceptionCodeDes.COOPERATION_PLATFORM_ORDERNO_NULL
							.getCode(),
					ExceptionCodeDes.COOPERATION_PLATFORM_ORDERNO_NULL
							.getDescription());
		} else if ("".equals(ptPayTime) || ptPayTime == null) {
			throw new ServerDisponseException(
					ExceptionCodeDes.BUYERS_PAYMENT_TIME_NULL.getCode(),
					ExceptionCodeDes.BUYERS_PAYMENT_TIME_NULL.getDescription());
		} else if ("".equals(buyNum) || buyNum == null) {
			throw new ServerDisponseException(
					ExceptionCodeDes.BUYE_GOODS_NUM_NULL.getCode(),
					ExceptionCodeDes.BUYE_GOODS_NUM_NULL.getDescription());
		} else if ("".equals(unitPrice) || unitPrice == null) {
			throw new ServerDisponseException(
					ExceptionCodeDes.GOODS_SUPPLY_PRICE_NULL.getCode(),
					ExceptionCodeDes.GOODS_SUPPLY_PRICE_NULL.getDescription());
		} else if ("".equals(sum) || sum == null) {
			throw new ServerDisponseException(
					ExceptionCodeDes.TRADE_AMOUNT_NULL.getCode(),
					ExceptionCodeDes.TRADE_AMOUNT_NULL.getDescription());
		} else if ("".equals(buyerIp) || buyerIp == null) {
			throw new ServerDisponseException(
					ExceptionCodeDes.USER_IP_NULL.getCode(),
					ExceptionCodeDes.USER_IP_NULL.getDescription());
		} else if ("".equals(notifyUrl) || notifyUrl == null) {
			throw new ServerDisponseException(
					ExceptionCodeDes.NOTIFY_URL_NULL.getCode(),
					ExceptionCodeDes.NOTIFY_URL_NULL.getDescription());
		} else {
			if ("2".equals(productType)) {
				if ("".equals(accountVal) || accountVal == null) {
					throw new ServerDisponseException(
							ExceptionCodeDes.RECHARGE_ACCOUNT_null.getCode(),
							ExceptionCodeDes.RECHARGE_ACCOUNT_null
									.getDescription());
				}
			}
			flag = true;
		}

		return flag;
	}

	/**
	 * 生成签名字符串
	 * 
	 * @param parameterInfo
	 *            交易接口参数对象
	 * @param productType
	 *            商品充值类型 1.卡密类型 2.自动冲类型
	 * @return
	 */
	private String createSignStr(NutsNetTradeParameter parameterInfo,
			String productType, String partnerKey, String supUserKey) {
		// 充值账户类型
		String accountType = parameterInfo.getAccountType();
		// 充值账号
		String accountVal = parameterInfo.getAccountVal();
		// 最终购买用户IP地址
		String buyerIp = parameterInfo.getBuyerIp();
		// 购买数量
		String buyNum = parameterInfo.getBuyNum();
		// 充值方式或计费类型
		String chargeType = parameterInfo.getChargeType();
		// 充值区域名称
		String gameArea = parameterInfo.getGameArea();
		// 充值服务器名称
		String gameSrv = parameterInfo.getGameSrv();
		// 赠品
		String gift = parameterInfo.getGift();
		// 内部账户类型
		String hidAccountType = parameterInfo.getHidAccountType();
		// 内部计费方式
		String hidChargeType = parameterInfo.getHidChargeType();
		// 内部充值区域
		String hidGameArea = parameterInfo.getHidGameArea();
		// 内部充值服务器
		String hidGameSrv = parameterInfo.getHidGameSrv();
		// 内部赠品信息
		String hidGift = parameterInfo.getHidGift();
		// 内部其他信息
		String hidOtherInfo = parameterInfo.getHidOtherInfo();
		// 异步通知地址
		String notifyUrl = parameterInfo.getNotifyUrl();
		// 其他信息
		String otherInfo = parameterInfo.getOtherInfo();
		// 合作平台编号
		String partnerId = parameterInfo.getPartnerId();
		// 合作方平台订单编号
		String ptOrderNo = parameterInfo.getPtOrderNo();
		// 合作方买家付款时间
		String ptPayTime = parameterInfo.getPtPayTime();
		// 总价
		String sum = parameterInfo.getSum();
		// 商品中心商品编号
		String supProductId = parameterInfo.getSupProductId();
		// 合作方用户编号
		String supUserId = parameterInfo.getSupUserId();
		// Sup供货价格单价
		String unitPrice = parameterInfo.getUnitPrice();

		StringBuilder strBu = new StringBuilder();

		if (!("".equals(accountType)) && accountType != null) {
			strBu.append("accountType");
			strBu.append(accountType);
		}
		if ("2".equals(productType)) { // 直充（非卡密）
			strBu.append("accountVal");
			strBu.append(accountVal);
		}

		strBu.append("buyerIp");
		strBu.append(buyerIp);
		strBu.append("buyNum");
		strBu.append(buyNum);

		if (!("".equals(chargeType)) && chargeType != null) {
			strBu.append("chargeType");
			strBu.append(chargeType);
		}
		if (!("".equals(gameArea)) && gameArea != null) {
			strBu.append("gameArea");
			strBu.append(gameArea);
		}
		if (!("".equals(gameSrv)) && gameSrv != null) {
			strBu.append("gameSrv");
			strBu.append(gameSrv);
		}
		if (!("".equals(gift)) && gift != null) {
			strBu.append("gift");
			strBu.append(gift);
		}
		if (!("".equals(hidAccountType)) && hidAccountType != null) {
			strBu.append("hidAccountType");
			strBu.append(hidAccountType);
		}
		if (!("".equals(hidChargeType)) && hidChargeType != null) {
			strBu.append("hidChargeType");
			strBu.append(hidChargeType);
		}
		if (!("".equals(hidGameArea)) && hidGameArea != null) {
			strBu.append("hidGameArea");
			strBu.append(hidGameArea);
		}
		if (!("".equals(hidGameSrv)) && hidGameSrv != null) {
			strBu.append("hidGameSrv");
			strBu.append(hidGameSrv);
		}
		if (!("".equals(hidGift)) && hidGift != null) {
			strBu.append("hidGift");
			strBu.append(hidGift);
		}
		if (!("".equals(hidOtherInfo)) && hidOtherInfo != null) {
			strBu.append("hidOtherInfo");
			strBu.append(hidOtherInfo);
		}
		if (!("".equals(notifyUrl)) && notifyUrl != null) {
			strBu.append("notifyUrl");
			strBu.append(notifyUrl);
		}
		if (!("".equals(otherInfo)) && otherInfo != null) {
			strBu.append("otherInfo");
			strBu.append(otherInfo);
		}

		strBu.append("partnerId");
		strBu.append(partnerId);
		strBu.append("ptOrderNo");
		strBu.append(ptOrderNo);
		strBu.append("ptPayTime");
		strBu.append(ptPayTime);
		strBu.append("sum");
		strBu.append(sum);
		strBu.append("supProductId");
		strBu.append(supProductId);
		strBu.append("supUserId");
		strBu.append(supUserId);
		strBu.append("unitPrice");
		strBu.append(unitPrice);
		strBu.append(partnerKey);
		strBu.append(supUserKey);

		String data = strBu.toString();
		String signStr = UtilMD5Encryption.createMD5Encryption(data);

		return signStr;
	}

	/**
	 * http请求url所传参数字符串拼接
	 * 
	 * @param parameterInfo
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	private String assembleParameter(NutsNetTradeParameter parameterInfo)
			throws UnsupportedEncodingException {
		StringBuffer strBuf = new StringBuffer();
		strBuf.append("partnerId=");
		strBuf.append(parameterInfo.getPartnerId());
		strBuf.append("&");
		strBuf.append("supUserId=");
		strBuf.append(parameterInfo.getSupUserId());
		strBuf.append("&");
		strBuf.append("supProductId=");
		strBuf.append(parameterInfo.getSupProductId());
		strBuf.append("&");
		strBuf.append("ptOrderNo=");
		strBuf.append(parameterInfo.getPtOrderNo());
		strBuf.append("&");
		strBuf.append("ptPayTime=");
		strBuf.append(parameterInfo.getPtPayTime());
		strBuf.append("&");
		strBuf.append("buyNum=");
		strBuf.append(parameterInfo.getBuyNum());
		strBuf.append("&");
		strBuf.append("unitPrice=");
		strBuf.append(parameterInfo.getUnitPrice());
		strBuf.append("&");
		strBuf.append("sum=");
		strBuf.append(parameterInfo.getSum());
		String accountVal = parameterInfo.getAccountVal();
		if (!("".equals(accountVal)) && accountVal != null) {
			strBuf.append("&");
			strBuf.append("accountVal=");
			strBuf.append(accountVal);
		}
		strBuf.append("&");
		strBuf.append("buyerIp=");
		strBuf.append(parameterInfo.getBuyerIp());
		String accountType = parameterInfo.getAccountType();
		if (!("".equals(accountType)) && accountType != null) {
			strBuf.append("&");
			strBuf.append("accountType=");
			strBuf.append(accountType);
		}
		String chargeType = parameterInfo.getChargeType();
		if (!("".equals(chargeType)) && chargeType != null) {
			strBuf.append("&");
			strBuf.append("chargeType=");
			strBuf.append(chargeType);
		}
		String gameArea = parameterInfo.getGameArea();
		if (!("".equals(gameArea)) && gameArea != null) {
			gameArea = URLEncoder.encode(gameArea, "GBK"); // GBK编码
			strBuf.append("&");
			strBuf.append("gameArea=");
			strBuf.append(gameArea);
		}
		String gameSrv = parameterInfo.getGameSrv();
		if (!("".equals(gameSrv)) && gameSrv != null) {
			gameSrv = URLEncoder.encode(gameSrv, "GBK"); // GBK编码
			strBuf.append("&");
			strBuf.append("gameSrv=");
			strBuf.append(gameSrv);
		}
		String gift = parameterInfo.getGift();
		if (!("".equals(gift)) && gift != null) {
			gift = URLEncoder.encode(gift, "GBK"); // GBK编码
			strBuf.append("&");
			strBuf.append("gift=");
			strBuf.append(gift);
		}
		String otherInfo = parameterInfo.getOtherInfo();
		if (!("".equals(otherInfo)) && otherInfo != null) {
			otherInfo = URLEncoder.encode(otherInfo, "GBK"); // GBK编码
			strBuf.append("&");
			strBuf.append("otherInfo=");
			strBuf.append(otherInfo);
		}
		String hidChargeType = parameterInfo.getHidChargeType();
		if (!("".equals(hidChargeType)) && hidChargeType != null) {
			strBuf.append("&");
			strBuf.append("hidChargeType=");
			strBuf.append(hidChargeType);
		}
		String hidAccountType = parameterInfo.getHidAccountType();
		if (!("".equals(hidAccountType)) && hidAccountType != null) {
			strBuf.append("&");
			strBuf.append("hidAccountType=");
			strBuf.append(hidAccountType);
		}
		String hidGameArea = parameterInfo.getHidGameArea();
		if (!("".equals(hidGameArea)) && hidGameArea != null) {
			hidGameArea = URLEncoder.encode(hidGameArea, "GBK"); // GBK编码
			strBuf.append("&");
			strBuf.append("hidGameArea=");
			strBuf.append(hidGameArea);
		}
		String hidGameSrv = parameterInfo.getHidGameSrv();
		if (!("".equals(hidGameSrv)) && hidGameSrv != null) {
			hidGameSrv = URLEncoder.encode(hidGameSrv, "GBK"); // GBK编码
			strBuf.append("&");
			strBuf.append("hidGameSrv=");
			strBuf.append(hidGameSrv);
		}
		String hidGift = parameterInfo.getHidGift();
		if (!("".equals(hidGift)) && hidGift != null) {
			hidGift = URLEncoder.encode(hidGift, "GBK"); // GBK编码
			strBuf.append("&");
			strBuf.append("hidGift=");
			strBuf.append(hidGift);
		}
		String hidOtherInfo = parameterInfo.getHidOtherInfo();
		if (!("".equals(hidOtherInfo)) && hidOtherInfo != null) {
			hidOtherInfo = URLEncoder.encode(hidOtherInfo, "GBK"); // GBK编码
			strBuf.append("&");
			strBuf.append("hidOtherInfo=");
			strBuf.append(hidOtherInfo);
		}

		strBuf.append("&");
		strBuf.append("notifyUrl=");
		strBuf.append(parameterInfo.getNotifyUrl());
		strBuf.append("&");
		strBuf.append("sign=");
		strBuf.append(parameterInfo.getSign());

		String paraStr = strBuf.toString();
		return paraStr;
	}

}
